package com.globant;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.globant.UserService;
import com.globant.exceptions.InvalidEmailException;
import com.globant.profy.model.Languages;
import com.globant.profy.model.Permisos;
import com.globant.profy.model.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
	boolean flag;
	private UserService userService;
	public static String[] availableLanguages = { "Spanish", "English",
			"German", "Italian", "French", "Portuguese" };

	@RequestMapping(value = "/user/home.do", method = RequestMethod.GET)
	public ModelAndView login(HttpServletRequest request,
			HttpServletResponse response) {
		return new ModelAndView("home", "role",
				request.isUserInRole("ROLE_ADMIN"));
	}

	@RequestMapping(value = "/user/dashboards.do", method = RequestMethod.GET)
	public String home2Dashboard(HttpServletRequest request,
			HttpServletResponse response, Model model) {

		Integer iPage = 0;
		List<User> users = userService.getAllUsers();

		model = nextPage(users, iPage, model);
		model.addAttribute("mode", "mode_all");
		model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));

		return "dashboards";
	}

	@RequestMapping(value = "/user/profiles.do", method = RequestMethod.GET)
	public String home2Profiles(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String mail = request.getUserPrincipal().getName();
		User user = userService.getUserByEmail(mail);

		List<Languages> list = user.getLanguages();
		List<String> userLanguages = new ArrayList<String>();
		for (int i = 0; i < list.size(); i++) {
			userLanguages.add(list.get(i).getIdioma());
		}

		ArrayList<String> notSpokenLanguages = new ArrayList<String>();
		ArrayList<String> AllSpokenLanguages = arrayToList(availableLanguages);
		for (int i = 0; i < AllSpokenLanguages.size(); i++) {
			flag = false;
			for (int j = 0; j < userLanguages.size(); j++) {
				if (AllSpokenLanguages.get(i).equals(userLanguages.get(j))) {
					flag = true;
				}
			}
			if (!flag) {
				notSpokenLanguages.add(AllSpokenLanguages.get(i));
			}

		}

		model.addAttribute("user_languages", userLanguages);
		model.addAttribute("notSpokenLanguages", notSpokenLanguages);
		model.addAttribute("user", user);
		model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));
		return "editUser";
	}

	@RequestMapping(value = "/user/createUser.do", method = RequestMethod.POST)
	public String dashboard2Create(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		model.addAttribute("availableLanguages", availableLanguages);
		model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));
		return "createUser";
	}

	@RequestMapping(value = "/user/editUser.do", method = RequestMethod.POST)
	public String dashboard2Edit(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String mail = request.getParameter("user_email");
		User user = userService.getUserByEmail(mail);

		List<Languages> list = user.getLanguages();
		List<String> userLanguages = new ArrayList<String>();
		for (int i = 0; i < list.size(); i++) {
			userLanguages.add(list.get(i).getIdioma());
		}
		ArrayList<String> notSpokenLanguages = new ArrayList<String>();
		ArrayList<String> AllSpokenLanguages = arrayToList(availableLanguages);
		for (int i = 0; i < AllSpokenLanguages.size(); i++) {
			flag = false;
			for (int j = 0; j < userLanguages.size(); j++) {
				if (AllSpokenLanguages.get(i).equals(userLanguages.get(j))) {
					flag = true;
				}
			}
			if (!flag) {
				notSpokenLanguages.add(AllSpokenLanguages.get(i));
			}

		}

		model.addAttribute("user_languages", userLanguages);
		model.addAttribute("notSpokenLanguages", notSpokenLanguages);
		model.addAttribute("user", user);
		model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));
		model.addAttribute("mode", "editUser");
		return "editUser";
	}

	private ArrayList<String> arrayToList(String[] array) {
		ArrayList<String> list = new ArrayList<String>();
		for (int i = 0; i < array.length; i++) {
			list.add(array[i]);
		}
		return list;
	}

	@RequestMapping(value = "/user/deleteUser.do", method = RequestMethod.POST)
	public String dashboard2Delete(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String mail = request.getParameter("user_email");
		User user = userService.getUserByEmail(mail);
		userService.deleteUser(user);
		return "redirect:/user/dashboards.do";
	}

	@RequestMapping(value = "/user/editUser2Dashboard.do", method = RequestMethod.POST)
	public String editUser2Dashboard(HttpServletRequest request,
			HttpServletResponse response, User user, Model model) {
		User user2 = userService.getUserByEmail(user.getEmail());
		user2.setExperience(user.getExperience());

		String[] language_list = request.getParameterValues("languages_list");
		List<Languages> list = new ArrayList<Languages>();
		if (language_list != null) {
			for (int i = 0; i < language_list.length; i++) {
				Languages lang = new Languages();
				lang.setIdioma(language_list[i]);
				list.add(lang);
			}
		}
		user2.setLanguages(list);

		List<Languages> lang_list = user2.getLanguages();
		List<String> userLanguages = new ArrayList<String>();
		for (int i = 0; i < lang_list.size(); i++) {
			userLanguages.add(lang_list.get(i).getIdioma());
		}

		ArrayList<String> notSpokenLanguages = new ArrayList<String>();
		ArrayList<String> AllSpokenLanguages = arrayToList(availableLanguages);
		for (int i = 0; i < AllSpokenLanguages.size(); i++) {
			flag = false;
			for (int j = 0; j < userLanguages.size(); j++) {
				if (AllSpokenLanguages.get(i).equals(userLanguages.get(j))) {
					flag = true;
				}
			}
			if (!flag) {
				notSpokenLanguages.add(AllSpokenLanguages.get(i));
			}

		}

		try {
			userService.updateUser(user2);
		} catch (Exception e) {
			String errorMessage = e.toString();
			model.addAttribute("error", errorMessage);
			model.addAttribute("user_languages", userLanguages);
			model.addAttribute("notSpokenLanguages", notSpokenLanguages);
			model.addAttribute("user", user2);
			model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));
			return "editUser";
		}
		return "redirect:/user/dashboards.do";
	}

	@RequestMapping(value = "/user/editUser2Dashboard2.do", method = RequestMethod.POST)
	public String editUser2Dashboard2(HttpServletRequest request,
			HttpServletResponse response, User user, Model model)
			throws Exception {
		User user2 = userService.getUserByEmail(user.getEmail());
		user2.setExperience(user.getExperience());

		String[] language_list = request.getParameterValues("languages_list");
		List<Languages> list = new ArrayList<Languages>();
		if (language_list != null) {
			for (int i = 0; i < language_list.length; i++) {
				Languages lang = new Languages();
				lang.setIdioma(language_list[i]);
				list.add(lang);
			}
		}
		user2.setLanguages(list);

		List<Languages> lang_list = user2.getLanguages();
		List<String> userLanguages = new ArrayList<String>();
		for (int i = 0; i < lang_list.size(); i++) {
			userLanguages.add(lang_list.get(i).getIdioma());
		}

		ArrayList<String> notSpokenLanguages = new ArrayList<String>();
		ArrayList<String> AllSpokenLanguages = arrayToList(availableLanguages);
		for (int i = 0; i < AllSpokenLanguages.size(); i++) {
			flag = false;
			for (int j = 0; j < userLanguages.size(); j++) {
				if (AllSpokenLanguages.get(i).equals(userLanguages.get(j))) {
					flag = true;
				}
			}
			if (!flag) {
				notSpokenLanguages.add(AllSpokenLanguages.get(i));
			}

		}

		try {
			userService.updateUser(user2);
		} catch (Exception e) {
			String errorMessage = e.toString();
			model.addAttribute("error", errorMessage);
			System.out.println(errorMessage);
			model.addAttribute("user_languages", userLanguages);
			model.addAttribute("notSpokenLanguages", notSpokenLanguages);
			model.addAttribute("user", user2);
			model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));
			return "editUser";
		}
		return "redirect:/user/home.do";
	}

	@RequestMapping(value = "/user/createUser2Dashboard.do", method = RequestMethod.POST)
	public String createUser2Dashboard(HttpServletRequest request,
			HttpServletResponse response, User user, Model model) {
		String[] language_list = request.getParameterValues("languages_list");

		String role = request.getParameter("role");

		if ("admin".equals(role)) {
			Permisos perm = new Permisos("ROLE_ADMIN");
			perm.setInfo("Permission given");
			user.setPermission(perm);
		} else {
			Permisos perm = new Permisos("ROLE_USER");
			perm.setInfo("Permission given");
			user.setPermission(perm);
		}

		List<Languages> list = new ArrayList<Languages>();
		if (language_list != null) {
			for (int i = 0; i < language_list.length; i++) {
				Languages lang = new Languages();
				lang.setIdioma(language_list[i]);
				list.add(lang);
			}
		}
		user.setLanguages(list);
		try {
			userService.createUser(user);
		} catch (Exception e) {
			String errorMessage = e.toString();
			model.addAttribute("error", errorMessage);
			model.addAttribute("availableLanguages", availableLanguages);
			model.addAttribute("user", user);
			model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));
			return "createUser";
		}
		return "redirect:/user/dashboards.do";

	}

	@RequestMapping(value = "/user/searchUser.do", method = RequestMethod.POST)
	public String dashboard2Search(HttpServletRequest request,
			HttpServletResponse response, Model model) {

		String searchText = request.getParameter("search");
		List<User> users = userService.getUserByCriteria(searchText);

		Integer iPage = 0;
		model = nextPage(users, iPage, model);

		model.addAttribute("searchText", searchText);
		model.addAttribute("mode", "mode_search");
		model.addAttribute("role", request.isUserInRole("ROLE_ADMIN"));

		return "dashboards";
	}

	@RequestMapping(value = "/user/nextPage.do", method = RequestMethod.POST)
	public String dashboard2NextPage(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String page = request.getParameter("page");
		String mode = request.getParameter("mode");
		String searchText = request.getParameter("search");

		Integer iPage = Integer.parseInt(page);

		if (mode.equals("mode_search")) {
			List<User> users = userService.getUserByCriteria(searchText);
			model = nextPage(users, iPage, model);
			model.addAttribute("mode", "mode_search");
			model.addAttribute("searchText", searchText);
		} else {
			List<User> users = userService.getAllUsers();
			model = nextPage(users, iPage, model);
			model.addAttribute("mode", "mode_all");
		}

		return "dashboards";
	}

	/**
	 * Validates if email is not registered and of a valid format so that a new
	 * User can be created with this email address For this, it uses two
	 * methods: isRegistered() and isValid()
	 * 
	 * 
	 * @param List
	 *            <User> Users you want to show, Integer The page you are now,
	 *            Model the model you
	 * @return Model
	 */

	private Model nextPage(List<User> users, Integer iPage, Model model) {
		boolean morePages = false;
		List<User> twentyUsers = new ArrayList<User>();

		if (users.size() > (5 * (iPage + 1))) {
			morePages = true;
			for (int i = 5 * iPage; i < (5 * iPage) + 5; i++) {
				twentyUsers.add(users.get(i));
			}
		} else {
			for (int i = 5 * iPage; i < users.size(); i++) {
				twentyUsers.add(users.get(i));
			}
		}
		iPage = iPage + 1;
		String page = Integer.toString(iPage);
		model.addAttribute("page", page);
		model.addAttribute("morePages", morePages);
		model.addAttribute("users", twentyUsers);
		return model;
	}

	@RequestMapping(value = "/user/prevPage.do", method = RequestMethod.POST)
	public String dashboard2PrevPage(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String page = request.getParameter("page");
		String mode = request.getParameter("mode");
		String searchText = request.getParameter("search");
		Integer iPage = Integer.parseInt(page);
		iPage = iPage - 2;

		if (mode.equals("mode_search")) {
			List<User> users = userService.getUserByCriteria(searchText);
			model = nextPage(users, iPage, model);
			model.addAttribute("mode", "mode_search");
			model.addAttribute("searchText", searchText);
		} else {
			List<User> users = userService.getAllUsers();
			model = nextPage(users, iPage, model);
			model.addAttribute("mode", "mode_all");
		}

		return "dashboards";
	}

	public UserService getUserSerivce() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}
}